package com.kb.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.TypeReference;
import cn.hutool.core.date.SystemClock;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kb.common.ApiResponse;
import com.kb.entity.digikey.Digikey;
import com.kb.entity.digikey.ProductData;
import com.kb.entity.digikey.QueryTO;
import com.kb.entity.digikey.RequestInfo;
import com.kb.entity.icQuote.Token;
import com.kb.mapper.mysql.digikey.DigikeyMapper;
import com.kb.mapper.mysql.digikey.RequestInfoMapper;
import com.kb.mapper.mysql.icQuote.TokenMapper;
import com.kb.service.DigikeyService;
import com.kb.util.MessageUtil;
import com.kb.util.ProductDetailsFetcher;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.Proxy;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.apache.log4j.Logger;

@Service
@DS("master")
@Slf4j
public class DigikeyServiceImpl implements DigikeyService {


    private String url = "https://api.digikey.com/v1/oauth2/token";
    private String clientId ="lnGfrAAGJZMWdzRYe7eJTEn5tgEl0eKc";

    private String clientSecret ="1aUJX2eqqnh9oaja";

    private String grantType ="client_credentials";

    @Resource
    private DigikeyMapper mapper;
    @Resource
    private TokenMapper tokenMapper;
    @Resource
    private RequestInfoMapper requestInfoMapper;

    @Resource
    private QuoteServiceImpl quoteService;

    @Override
    public String updateToken() {
        try {
            String postData = "client_id=" + URLEncoder.encode(clientId, "UTF-8") +
                    "&client_secret=" + URLEncoder.encode(clientSecret, "UTF-8") +
                    "&grant_type=" + URLEncoder.encode(grantType, "UTF-8");

            // 发送POST请求，使用HttpUtil
            String responseBody = HttpUtil.post(url, postData);

            // 解析 JSON
            JSONObject jsonObject = new JSONObject(responseBody);
            Date currentDate = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedDate = dateFormat.format(currentDate);
            log.info(formattedDate + " token结果为: " + jsonObject);
            // 提取 access_token 和 expires_in
            String token = jsonObject.getStr("access_token");
            Long time = jsonObject.getLong("expires_in");


            if(StringUtils.isNotBlank(token)&&time!=null){
                QueryWrapper<Token> wrapper=new QueryWrapper();
                wrapper.eq("type",3);
                Token existingToken=tokenMapper.selectOne(wrapper);

                if (existingToken == null) {
                    Token newToken = new Token();
                    newToken.setToken(token);
                    newToken.setExpireTime(time);
                    newToken.setType(3);
                    tokenMapper.insert(newToken);
                } else {
                    existingToken.setExpireTime(time);
                    existingToken.setToken(token);
                    tokenMapper.updateById(existingToken);
                }
                return token;
            }

            return null;
        } catch (HttpException e) {
           log.error(String.valueOf(e));
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

    }


    @Override
    @Async // 使用异步处理
    public CompletableFuture<List<ProductData>> getQuoteAsync(QueryTO to) throws JsonProcessingException, ExecutionException, InterruptedException {
        // 保持原来同步方法的逻辑
        List<ProductData> result = getQuote(to);  // 调用原有的同步方法
        return CompletableFuture.completedFuture(result);
    }

    //看板请求昴氏
    @Override
    @Scheduled(cron = "0 12 * * * ?")
    public ApiResponse excuteMouser() throws UnsupportedEncodingException {
        QueryWrapper<RequestInfo> wrapper=new QueryWrapper();
        wrapper.eq("type",1);
        RequestInfo request = requestInfoMapper.selectOne(wrapper);
        long startTime = SystemClock.now();

        try {
            String url = "http://192.168.10.92:8010/mouser.ashx?cmd=enquiry";
            String postData = "mfc=" + URLEncoder.encode("TLS203B0EJV33XUMA1", "UTF-8");

            String str = HttpRequest.post(url)
                    .timeout(30000) // 设置连接超时和读取超时为30秒
                    .body(postData)
                    .execute()
                    .body();

            JSONObject jsonObject = JSONUtil.parseObj(str);

            // 提取 success 字段的值
            Integer success = jsonObject.getInt("code");

            // 记录请求结束时间
            long endTime = SystemClock.now();

            // 计算请求时间（秒）
            double consumingTime = (endTime - startTime) / 1000.0;  // 秒数（小数）

            // 设置到 consuming 字段，保留两位小数
            request.setConsuming(Math.round(consumingTime * 100.0) / 100.0);

            if(success==0){
                request.setIsSuccess(1);
            }else{
                request.setIsSuccess(2);
            }
            request.setInfo(str);
        } catch (Exception e) {

            request.setIsSuccess(2);
            request.setInfo(e.toString());
        }
        finally {
            request.setRequestTime(new Date());
            requestInfoMapper.updateById(request);
            if(request.getIsSuccess()==2){
                MessageUtil.sentMessage("25313", "昴氏,错误信息:"+request.getInfo(), "元器件请求失败");
            }
        }


        return ApiResponse.successBaida("请求昴氏成功");

    }

    @Override
    @Scheduled(cron = "0 24 * * * ?")
    public ApiResponse excuteDigikey() {

        QueryWrapper<RequestInfo> wrapper = new QueryWrapper();
        wrapper.eq("type", 2);
        RequestInfo info = requestInfoMapper.selectOne(wrapper);

        // 记录请求开始时间
        long startTime = SystemClock.now();

        try {
            String token = getToken(3);

            String jsonBody = "{"
                    + "\"KeyWord\": \"" + "454-1647-ND" + "\","
                    + "\"Currency\": \"" + "RMB" + "\","
                    + "\"token\": \"" + token + "\""
                    + "}";

            HttpRequest request = HttpRequest.post("http://8.155.30.82:5000/api/DigikeyApi/GetProductDetails")
                    .header("Content-Type", "application/json")  // 设置请求头
                    .timeout(60000)  // 设置超时时间
                    .body(jsonBody);

            HttpResponse detailResponse = request.execute();

            String detailResponseBody = detailResponse.body();

            // 记录请求结束时间
            long endTime = SystemClock.now();

            // 计算请求时间（秒）
            double consumingTime = (endTime - startTime) / 1000.0;  // 秒数（小数）

            // 设置到 consuming 字段，保留两位小数
            info.setConsuming(Math.round(consumingTime * 100.0) / 100.0);

            if (detailResponseBody.contains("Exception")) {
                info.setIsSuccess(2);
            } else {
                info.setIsSuccess(1);
            }

            info.setInfo(detailResponseBody);

        } catch (Exception e) {
            info.setIsSuccess(2);
            info.setInfo(e.toString());

        } finally {
            info.setRequestTime(new Date());
            requestInfoMapper.updateById(info);

            if (info.getIsSuccess() == 2) {
                MessageUtil.sentMessage("25313", "得捷,错误信息:" + info.getInfo(), "元器件请求失败");
            }
        }

        return ApiResponse.successBaida("请求得捷成功");
    }

    @Override
    @Scheduled(cron = "0 36 * * * ?")
    public ApiResponse excuteElement() throws UnsupportedEncodingException {
        QueryWrapper<RequestInfo> wrapper=new QueryWrapper();
        wrapper.eq("type",3);
        RequestInfo request = requestInfoMapper.selectOne(wrapper);
        // 记录请求开始时间
        long startTime = SystemClock.now();
        try {
            String url = "http://192.168.10.92:8010/element.ashx?cmd=enquiry";

// 准备要发送的参数（x-www-form-urlencoded 格式）
            String postData = "code=" + URLEncoder.encode("EVAL-AD7195ASDZ", "UTF-8"); // 对code进行URL编码

// 发送POST请求
            String str = HttpUtil.post(url, postData);

            JSONObject jsonObject = JSONUtil.parseObj(str);

            // 提取 success 字段的值
            Integer success = jsonObject.getInt("code");

            // 记录请求结束时间
            long endTime = SystemClock.now();

            // 计算请求时间（秒）
            double consumingTime = (endTime - startTime) / 1000.0;  // 秒数（小数）

            // 设置到 consuming 字段，保留两位小数
            request.setConsuming(Math.round(consumingTime * 100.0) / 100.0);

            if(success==0){
                request.setIsSuccess(1);
            }else{
                request.setIsSuccess(2);
            }


            request.setInfo(str);

        } catch (Exception e) {

            request.setIsSuccess(2);
            request.setInfo(e.toString());

        } finally {
            request.setRequestTime(new Date());
            requestInfoMapper.updateById(request);
            if(request.getIsSuccess()==2){
                MessageUtil.sentMessage("25313", "易络盟,错误信息:"+request.getInfo(), "元器件请求失败");
            }

        }

        return ApiResponse.successBaida("请求易络盟成功");

    }

    @Override
    @Scheduled(cron = "0 48 * * * ?")
    public ApiResponse excuteYunhan() {

        QueryWrapper<RequestInfo> wrapper=new QueryWrapper();
        wrapper.eq("type",4);
        RequestInfo request = requestInfoMapper.selectOne(wrapper);
        // 记录请求开始时间
        long startTime = SystemClock.now();
        try {
            String token = getToken(1);
            long timestamp = Instant.now().getEpochSecond();
            Map<String, Object> jsonMap = new HashMap<>();
            jsonMap.put("_t", timestamp);
            jsonMap.put("token", token);
            jsonMap.put("keyword", "SQMR568KJ");
            String json = JSONUtil.toJsonStr(jsonMap);
            String response = quoteService.sendPostRequest("http://openapi.ickey.cn"+"/search-v1/products/get-single-goods-new", json);

            JSONObject jsonObject = JSONUtil.parseObj(response);

            // 提取 success 字段的值
            boolean success = jsonObject.getBool("success");

            // 记录请求结束时间
            long endTime = SystemClock.now();

            // 计算请求时间（秒）
            double consumingTime = (endTime - startTime) / 1000.0;  // 秒数（小数）

            // 设置到 consuming 字段，保留两位小数
            request.setConsuming(Math.round(consumingTime * 100.0) / 100.0);

            if(success){
                request.setIsSuccess(1);
            }else{
                request.setIsSuccess(2);
            }


            request.setInfo(response);

        } catch (Exception e) {
            request.setIsSuccess(2);
            request.setInfo(e.toString());

        } finally {
            request.setRequestTime(new Date());
            requestInfoMapper.updateById(request);

            if(request.getIsSuccess()==2){
                MessageUtil.sentMessage("25313", "云汉,错误信息:"+request.getInfo(), "元器件请求失败");
            }
        }

        return ApiResponse.successBaida("请求云汉成功");
    }

    @Override
    @Scheduled(cron = "0 0 * * * ?")
    public ApiResponse excuteSHT() {
        QueryWrapper<RequestInfo> wrapper=new QueryWrapper();
        wrapper.eq("type",5);
        RequestInfo request = requestInfoMapper.selectOne(wrapper);
        // 记录请求开始时间
        long startTime = SystemClock.now();

        try {
            Map<String, Object> jsonMap = new HashMap<>();

            String token=getToken(2);

            HttpResponse response = HttpRequest.post("http://t.bomman.com/api/oksht-external/v2/product/search")
                    .header("Blade-Auth", "bearer " + token)
                    .header("sht-auth", "external-service")
                    .body("{\"keyword\": \"" + "STM32F103VCT6" + "\", \"current\": 1, \"size\": 2000, \"type\": 1}")
                    .execute();

            String responseBody = response.body();

            JSONObject jsonObject = JSONUtil.parseObj(responseBody);

            // 提取 success 字段的值
            Integer success = jsonObject.getInt("code");

            // 记录请求结束时间
            long endTime = SystemClock.now();

            // 计算请求时间（秒）
            double consumingTime = (endTime - startTime) / 1000.0;  // 秒数（小数）

            // 设置到 consuming 字段，保留两位小数
            request.setConsuming(Math.round(consumingTime * 100.0) / 100.0);

            if(success==200){
                request.setIsSuccess(1);
            }else{
                request.setIsSuccess(2);
            }



            request.setInfo(responseBody);


        } catch (Exception e) {

            request.setIsSuccess(2);
            request.setInfo(e.toString());

        } finally {
            request.setRequestTime(new Date());
            requestInfoMapper.updateById(request);
            if(request.getIsSuccess()==2){
                MessageUtil.sentMessage("25313", "圣禾堂,错误信息:"+request.getInfo(), "元器件请求失败");
            }
        }
        return ApiResponse.successBaida("请求圣禾堂成功");
    }


    public List<ProductData> getQuote(QueryTO to) throws JsonProcessingException, ExecutionException, InterruptedException {
        try {
            String token = getToken(3);
            List<String> productNumbers = new ArrayList<>();
            List<ProductData> result = new ArrayList<>();
            QueryWrapper<Digikey> wrapper = new QueryWrapper<>();
            log.info("keyword: " + to.getKeyWord());
            log.info("currency: " + to.getCurrency());
            wrapper.eq("keyword", to.getKeyWord());
            wrapper.eq("currency", to.getCurrency());

            List<Digikey> digikeyList = mapper.selectList(wrapper);

            Digikey digikey = null;
            if (!digikeyList.isEmpty()) {
                digikey = digikeyList.get(0); // 只取第一个结果
            }

            ObjectMapper objectMapper = new ObjectMapper();
            Boolean isExist = false;
            if (digikey != null) {
                log.info("系统有收录该关键字和币种");
                isExist = true;
                List<ProductData> quote = objectMapper.readValue(digikey.getJsondata(), new TypeReference<List<ProductData>>() {});
                if (quote != null && !quote.isEmpty()) {
                    for (ProductData data : quote) {
                        productNumbers.addAll(data.getProduct().getProductVariations().stream()
                                .filter(variation -> variation != null
                                        && variation.getPackageType() != null
                                        && variation.getPackageType().getName() != null
                                        && !variation.getPackageType().getName().contains("Digi-Reel"))
                                .map(ProductData.ProductVariation::getDigiKeyProductNumber)
                                .collect(Collectors.toList()));
                    }
                }

            }

            if (productNumbers.isEmpty()) {
                String jsonBody = "{"
                        + "\"KeyWord\": \"" + to.getKeyWord() + "\","
                        + "\"Currency\": \"" + to.getCurrency() + "\","
                        + "\"token\": \"" + token + "\""
                        + "}";

                // Make the HTTP request to the new endpoint
                HttpResponse response = HttpRequest.post("http://8.155.30.82:5000/api/DigikeyApi/GetQuote")
                        .header("Content-Type", "application/json")
                         // Include token in the header
                        .timeout(60000)
                        .body(jsonBody)
                        .execute();


                String responseBody = response.body();
                JSONObject jsonResponse = JSONUtil.parseObj(responseBody);
                JSONArray resultArray = new JSONArray();

// 优先匹配 ExactMatches 数据
                JSONArray exactMatchesArray = jsonResponse.getJSONArray("ExactMatches");
                if (exactMatchesArray != null && !exactMatchesArray.isEmpty()) {
                    resultArray = exactMatchesArray;  // 使用 ExactMatches 数据
                }

// 如果有 Products 数据，最多取前5个并添加到结果后面
                JSONArray productsArray = jsonResponse.getJSONArray("Products");
                if (productsArray != null && !productsArray.isEmpty()) {
                    int limit = Math.min(productsArray.size(), 5);  // 取 Products 中最多5个元素
                    for (int i = 0; i < limit; i++) {
                        resultArray.add(productsArray.get(i));  // 添加到结果数组后面
                    }
                }

                if(resultArray!=null){
                    for (int i = 0; i < resultArray.size(); i++) {
                        JSONObject product = resultArray.getJSONObject(i);
                        JSONArray productVariations = product.getJSONArray("ProductVariations");
                        for (int j = 0; j < productVariations.size(); j++) {
                            JSONObject variation = productVariations.getJSONObject(j);
                            JSONObject packageType = variation.getJSONObject("PackageType");
                            if (packageType != null && !packageType.getStr("Name").contains("Digi-Reel")) {
                                String digiKeyProductNumber = variation.getStr("DigiKeyProductNumber");
                                if (digiKeyProductNumber != null) {
                                    productNumbers.add(digiKeyProductNumber.replace("/", "%2F").replace("#", "%23"));
                                }
                            }
                        }
                    }
                }

            }

            // 异步获取产品详细信息
            if (!productNumbers.isEmpty()) {
                result = ProductDetailsFetcher.fetchProductDetails(productNumbers, token, to.getCurrency());
                result = filterProductData(result);
            }

            if (!result.isEmpty() && !isExist && StringUtils.isNotBlank(to.getKeyWord())) {
                log.info("系统暂时没有收录该关键字和币种");
                Digikey key = new Digikey();
                key.setId(UUID.randomUUID().toString());
                key.setCurrency(to.getCurrency());
                key.setJsondata(objectMapper.writeValueAsString(result));
                key.setKeyword(to.getKeyWord());
                mapper.insert(key);
            }

            if(result.isEmpty()){

                QueryWrapper<Digikey> keyWrapper = new QueryWrapper<>();
                keyWrapper.eq("keyword", to.getKeyWord());

                mapper.delete(keyWrapper);

            }

            return result;
        } catch (Exception e) {
            log.error("请求得捷关键字错误，物料为: " + to.getKeyWord(), e);
            throw new RuntimeException(e);
        }
    }



    public static List<ProductData> filterProductData(List<ProductData> productDataList) {
        // Step 1: Collect all digiKeyProductNumber occurrences
        Set<String> setList = new HashSet<>();
        List<ProductData> result = new ArrayList<>();

        for (ProductData productData : productDataList) {
            if (productData != null && productData.getProduct() != null && productData.getProduct().getProductVariations() != null) {
                boolean isPass = false;
                for (ProductData.ProductVariation variation : productData.getProduct().getProductVariations()) {
                    String digiKeyProductNumber = variation.getDigiKeyProductNumber();
                    if (setList.add(digiKeyProductNumber)) {
                        isPass = true;
                    }
                }
                if (isPass) {
                    result.add(productData);
                }
            }
        }
        return result;
    }


    private String getToken(Integer type){
        QueryWrapper<Token> wrapper=new QueryWrapper();
        wrapper.eq("type",type);
        Token existingToken=tokenMapper.selectOne(wrapper);

        if(existingToken!=null){
            return existingToken.getToken();
        }else{
           return updateToken();
        }



    }
}
